/***
 *
 * 用于实现模型剪切的类:Cliping.js
 *
 * Daniel
 *
 * 2018.03.16
 *
 * **/
define(["data"],function(datalist){
    
    var Cliping = function () {
        this.globalPlanesCounts = 0;
        this.sliding = 40;               //控制剪切面的拖动值
        this.boxColor = 0x6f7275;       //剖面体初始色
        this.boxFrameColor = 0x151515;       //剖面体边框色
        this.boxStateColor = 0x378a0e;       //剖面体状态色
        this.opacity = 0.2;                 //剖面体透明度
        
        this.world = {};
        this.event = {};
        this.assistFace = [];           //剖面
        this.indexVector = [];          //顶点索引器
        this.globalPlanesContainer = {};    //剖面总和
        this.indexFace = {};    //剖面索引器
        this.PlanesContainer = null;        //单个剖面
        this.aixsFace = null;               //剖面所处的物理界面
        this.PlaneGroup = {};               //剖面体
        this.clippingCube={
                width:250,
                height:100,
                depth:150,
                position:new THREE.Vector3(0,100,0)
        };              //剖面参数
        this.globalPlanes = [];
        this.clipingConset = [];            //剪切面距离值
        this.globalVertices = [];           //原始顶点容器
        this.Empty = Object.freeze( [] );
        
        
        
    };
    var that;
    
    //初始化
    Cliping.prototype.init = function(world,pick,clippingCube){
        that = this;
        //引入三维场景
        this.world = world;
        
        //引入拾取机制
        this.event = pick.pick();
        
        //剖面数据初始化
        this.clippingCube = clippingCube || this.clippingCube;
        this.scene = world.scene;
        
        //初始化剖面体
        //this.clippingAssist(this.clippingCube);
        this.clippingAssist();
        
        
        //默认植入剪切面
        
        //this.cube(new THREE.Vector3(),1000);
    
    };
    
    //剖面展示
    Cliping.prototype.clippingView = function (){
        
        var scope = this;
        var scene = scope.scene;
        return function(toggle){
           
            if(toggle!==undefined){
                
                //剖面设置
                //scope.world.renderer.localClippingEnabled = toggle;
                
                scope.world.renderer.clippingPlanes = toggle ? scope.globalPlanes : scope.Empty;
                var objcet = scene.getObjectByName("clippingGroup");
                if(toggle){
                    scope.assistFace.forEach(function(e){
                        if(e!==undefined)e.visible = true;
                    });
                    objcet.visible = true;
                    scope.enabled();
                }
                else{
                    scope.assistFace.forEach(function(e){
                        if(e!==undefined)e.visible = true;
                    });
                    objcet.visible = false;
                    scope.dispose();
                   
                }
        
            }else{
                var objcet = scene.getObjectByName("clippingGroup");
                    scene.remove(objcet);
            }
        };
        
    };
    
    //轴向剖面
    //Cliping.prototype.
    
    // //添加立体剖面
    // Cliping.prototype.cube = function(vector3,value){
    //     if(vector3 == undefined){
    //         value = 50;
    //         vector3 = new THREE.Vector3();
    //     }
    //
    //     var aixsF,aixsB,aixsL,aixsT,aixsD,aixsR;
    //     var faceF,faceB,faceL;
    //     var faceT,faceD,faceR;
    //
    //     aixsF = vector3.clone().setZ(value);
    //
    //     aixsT = vector3.clone().setY(value);
    //
    //     aixsL = vector3.clone().setX(value);
    //
    //     aixsR = vector3.clone().setX(-value);
    //
    //     aixsB = vector3.clone().setZ(-value);
    //
    //     aixsD = vector3.clone().setY(-value);
    //
    //     faceF = this.addClipping(new THREE.Vector3(0, 0, -1),"front",aixsF.z+0.1,aixsF);//正面剪切
    //
    //     faceL = this.addClipping(new THREE.Vector3(-1, 0, 0),"left",aixsL.x+0.1,aixsL);//左侧面剪切
    //
    //     faceD = this.addClipping(new THREE.Vector3(0, 1, 0),"down",(-aixsD.y)+0.1,aixsD);//底面剪切
    //
    //     faceB = this.addClipping(new THREE.Vector3(0, 0, 1),"back",(-aixsB.z)+0.1,aixsB);//背面剪切
    //
    //     faceR = this.addClipping(new THREE.Vector3(1, 0, 0),"right",(-aixsR.x)+0.1,aixsR);//右侧面剪切
    //
    //     faceT = this.addClipping(new THREE.Vector3(0, -1, 0),"top",aixsT.y+0.1,aixsT);//顶面剪切
    //
    //
    //
    //     this.assistFace.push(faceF,faceB,faceL,faceT,faceD,faceR);
    //
    //     return this.assistFace;
    // };
    //
    // //添加剖面
    //
    // Cliping.prototype.addClipping = function(normal,type,value,positions){
    //
    //     var normals,conset = 1;
    //     var name = "clipping" + this.globalPlanesCounts;
    //     var position = positions || new THREE.Vector3();
    //         normal !== undefined ? normals = normal : normals = new THREE.Vector3(0,-1,0);
    //     if(value)conset = value;
    //
    //     var clipings = this.createPlane(normals,conset);
    //     var geometry = new THREE.PlaneGeometry( 4000, 4000, 1 );
    //     var material = new THREE.MeshBasicMaterial( {color: 0x0aa770, side: 2, opacity:0.5, transparent:true} );
    //     var plane = new THREE.Mesh( geometry, material );
    //     var group = new THREE.Group();
    //
    //         group.flag = type || "random";
    //         group.name = name;
    //         group.visible = false;
    //         group.add(plane);
    //         group.position.copy(position);
    //         this.classify(group,clipings);
    //
    //     this.PlanesContainer[""+name+""] = group;
    //     this.globalPlanesId.push(name);
    //     this.scene.add(group);
    //     this.world.modelArray.push(group);
    //
    //     return group;
    //
    //
    // };
    // //剖面分类
    //
    // Cliping.prototype.classify = function(group,clipings){
    //     if(group == undefined && clipings == undefined)return;
    //     var count = group.position;
    //     switch (group.flag){
    //
    //         case "top":
    //
    //             //clipings.constant = count.y;
    //             group.children[0].rotation.set(-1/2*Math.PI,0,0);
    //
    //             break;
    //
    //         case "down":
    //
    //             //clipings.constant = count.y;
    //             group.children[0].rotation.set(1/2*Math.PI,0,0);
    //
    //             break;
    //
    //         case "front":
    //
    //             //clipings.constant = count.z;
    //             group.children[0].rotation.set(0,0,0);
    //
    //             break;
    //
    //         case "back":
    //
    //             //clipings.constant = count.z;
    //             group.children[0].rotation.set(-Math.PI,0,0);
    //
    //             break;
    //
    //         case "left":
    //
    //             //clipings.constant = count.x;
    //             group.children[0].rotation.set(0,-1/2*Math.PI,0);
    //
    //             break;
    //
    //         case "right":
    //
    //             //clipings.constant = count.x;
    //             group.children[0].rotation.set(0,1/2*Math.PI,0);
    //
    //             break;
    //
    //         default:
    //
    //             // clipings.constant = count.y;
    //
    //             break;
    //
    //
    //
    //     }
    //
    // };
    
    //剪切面生成器
    Cliping.prototype.createPlane = function (normal,conset,face) {
        var normals,consets;
        normals = normal || new THREE.Vector3(1,0,0);
        consets = conset || 100;
        var name = "clipping" + face;
        var clipings = new THREE.Plane(normals,consets);
        this.globalPlanesContainer[""+name+""] = clipings;
        this.indexFace[""+face+""] = clipings;
        this.globalPlanes.push(clipings);
        this.clipingConset.push(consets);
        return clipings;
    };
    
    //移动剖面
    Cliping.prototype.opeation = {
      
        remove:function(name){
        
        },
        
        add:function(type){
            if(type == undefined)return;
            
        
        },
        
        //清楚所有剪切面
        clear:function(){
            this.globalPlanesContainer = {};
            //this.PlanesContainer = {};
            this.globalPlanes.length=0;
            this.globalPlanesId.length = 0;
        },
        
        //剪切面控制器
        guide:function (name,value) {
            
            if(name == undefined && value == undefined)return;
            var clipings = this.globalPlanesContainer[name];
            if(!clipings)return;
            clipings.constant = value;
        }
        
    };
    
    //添加任意剖面
    Cliping.prototype.plan = function (vector3) {
        if(vector3==undefined)return;
        var face = this.createPlane(new THREE.Vector3(0, -1, 0),vector3.y);
        datalist.clipping.push(face);
        return face;
    };
    

    //剖面体
    Cliping.prototype.clippingAssist = function (width,height,depth,position){
        
        var width = width || 80;
        var height = height || 60;
        var depth = depth ||  50;
        var position = position || new THREE.Vector3();
        
        var clippingBox = new THREE.BoxGeometry(width, height, depth);
        var boxMaterials = new THREE.MeshBasicMaterial({
            color: this.boxColor,
            opacity: this.opacity,
            transparent:true,
            side:2,
            depthTest:false,
            flatShading: true,
            vertexColors: THREE.VertexColors
        });
        var clippingB = new THREE.Mesh(clippingBox, boxMaterials);
        var helper = new THREE.BoxHelper(clippingB,this.boxFrameColor);
        var clippingG = new THREE.Group();
        
        clippingB.nmae = "clipping";
        clippingG.add(clippingB);
        clippingG.add(helper);
        clippingG.position.copy(position);
        clippingG.name = "clippingGroup";
        clippingG.visible = false;
        
        this.scene.add(clippingG);
        this.PlaneGroup = clippingG;
        clippingBox.vertices.forEach(function(e){
            that.globalVertices.push(e.clone());
        });
        this.separateFace(clippingB);                       //生成剖面

    };
    
    //
    // //剖面拖拽
    // Cliping.prototype.clippingPick = function (event){
    //     var scope = this;
    //     var clippingTarget = scope.scene.getChildByName("clippingGroup").children;
    //     scope.pick(event,callback,clippingTarget);
    //
    //     function callback(objects)
    //     {
    //         var cameraBB = scope.scene.cameraList.camera;
    //         var controlsCameras = cameraBB.orbitControls;
    //         if(objects.length>0){
    //             controlsCameras.enableRotate = false;
    //             var targetObject = objects[0];
    //             var colors = 0x35b2f9;
    //             this.clippingChange(targetObject,colors);
    //
    //         }else{
    //             controlsCameras.enableRotate = true;
    //         }
    //
    //     }
    //
    // };
    //
    
    // //恢复
    // Cliping.prototype.clippingBack = function (event){
    //
    //     if (event) event.preventDefault();
    //     var cameraBB = scene.cameraList.camera;
    //     var controlsCameras = cameraBB.orbitControls;
    //     var targetObject = hoverData.cliping[0];
    //     var colors = 0x223456;
    //     controlsCameras.enableRotate = true;
    //     this.clippingChange(targetObject,colors);
    //
    // };
    
    //拾取更改剖面颜色
    Cliping.prototype.clippingChange = function (pram,colors,boolean){
        var meshData = pram.object;
        var facesIndex = pram.faceIndex;
        var facesArray = meshData.geometry.faces;
        var color = colors ;
        switch(facesIndex){
            case 0:
            case 1:
                changeColor(facesArray,0,1,color);
                this.aixsFace = "F";
                break;
            case 2:
            case 3:
                changeColor(facesArray,2,3,color);
                this.aixsFace = "B";
                break;
            case 4:
            case 5:
                changeColor(facesArray,4,5,color);
                this.aixsFace = "T";
                break;
            case 6:
            case 7:
                changeColor(facesArray,6,7,color);
                this.aixsFace = "D";
                break;
            case 8:
            case 9:
                changeColor(facesArray,8,9,color);
                this.aixsFace = "R";
                break;
            case 10:
            case 11:
                changeColor(facesArray,10,11,color);
                this.aixsFace = "L";
                break;
        }
        meshData.geometry.colorsNeedUpdate = true;
    };
    
    //剥离剖面体
    Cliping.prototype.separateFace = function (object){
        if(!object.isObject3D)return;
        var targetObject = object.geometry.faces;
        var project = [object.geometry.vertices[0]];
        var i = targetObject.length-1;
        var normal,conset;
        var aixsFace;
        for(;i>-1;i--){
            switch (i/2){
    
                //背面剪切
                case 0:
                    normal = targetObject[i].normal;
                    conset = 0.01 + project[0].x;
                    aixsFace = "B";
                    break;
    
                //正面剪切
                case 1:
                    normal = targetObject[i].normal;
                    conset = 0.01 + project[0].x;
                    aixsFace = "F";
                    break;
    
                //顶面剪切
                case 2:
                    normal = targetObject[i].normal;
                    conset = 0.01 + project[0].y;
                    aixsFace = "D";
                    break;
    
                //底面剪切
                case 3:
                    normal = targetObject[i].normal;
                    conset = 0.01 + project[0].y;
                    aixsFace = "T";
                    break;
    
                //左侧面剪切
                case 4:
                    normal = targetObject[i].normal;
                    conset = 0.01 + project[0].z;
                    aixsFace = "L";
                    break;
    
    
                //右侧面剪切
                case 5:
                    normal = targetObject[i].normal;
                    conset = 0.01 + project[0].z;
                    aixsFace = "R";
                    break;
                default:
                    continue;
            }
            this.createPlane(normal,conset,aixsFace);
        }
        return;
    };
    
    //激活鼠标事件
    Cliping.prototype.enabled = function(){
            document.addEventListener("mousedown",this.mousedown,false);
            document.addEventListener("mouseup",this.mouseup,false);
    };
    
    //移除鼠标事件
    Cliping.prototype.dispose = function(){
            document.removeEventListener("mousedown",this.mousedown,false);
            document.removeEventListener("mouseup",this.mouseup,false);
    };
    
    //鼠标摁下
    Cliping.prototype.mousedown = function (event){
        event.preventDefault();
        if(event.button !== 0)return;
        that.event(event,downEvent,that.PlaneGroup.children);
        if(that.PlanesContainer !== null){
            that.scene.children[0].orbitControls.enableRotate = false;
            that.world.stopRotate.dispose();
            document.addEventListener("mousemove",that.mousemove,false);
        }
    };
    
    //鼠标移动
    Cliping.prototype.mousemove = function (event){
        event.preventDefault();
        if(that.PlanesContainer !== null){
            moveEvent(event,that.PlanesContainer.object.geometry);
        }else{
            return;
        }
    };
    
    //鼠标抬起
    Cliping.prototype.mouseup = function (event){
        event.preventDefault();
        that.scene.children[0].orbitControls.enableRotate = true;
        that.world.stopRotate.enbale();
        if(that.PlanesContainer !== null){
            that.clippingChange(that.PlanesContainer,this.boxStateColor);
            that.PlanesContainer = null;
            document.removeEventListener("mousemove",that.mousemove,false);
        }
    };
    
    //恢复剖面
    Cliping.prototype.reset = function () {
        var object = this.PlaneGroup.children[0].geometry;
            object.vertices = this.globalVertices;
            object.verticesNeedUpdate = true;
        var face = this.globalPlanes;
        var consets = this.clipingConset;
        var i = face.length-1;
        for(;i>-1;i--)face[i].constant = consets[i];
    };
    
    
    //执行down
    function downEvent(project){
        
        if(project.length>0){
            
            var target = project[0];
            that.clippingChange(target,0x3fbf62,true);
            that.PlanesContainer = target;
            
        }else{
            
            that.PlanesContainer = null;
            
        };
        
    }
    
    //执行move
    function moveEvent(event,project) {
        
        if(project == undefined)return;
        var x = event.movementX;
        var y = event.movementY;
        var flag = that.aixsFace;
        var box = that.PlaneGroup.children;
        var object = project;
        var value = null;
        switch (flag){
            //X变化
            case "L":
            case "R":
                x == 0 ? value = 0 : value = (x/Math.abs(x))*that.sliding*0.05;
                vectorUpdate(value,object,flag);
                break;
    
            //Y变化
            case "T":
            case "D":
                y == 0 ? value = 0 : value = (y/Math.abs(y))*that.sliding*0.05;
                vectorUpdate(value,object,flag);
                break;
                
            case "B":
            case "F":
                y == 0 ? value = 0 : value = (y/Math.abs(y))*that.sliding*0.05;
                vectorUpdate(value,object,flag);
                break;
                
        }
        box[1].setFromObject(box[0]);
    
    }
    
    // //更新材质
    // function needsUpdate ( material, geometry ) {
    //
    //     return function () {
    //
    //         material.side = +material.side; //Ensure number
    //         //material.color = new THREE.Color(0xff0000); //Ensure number
    //         material.needsUpdate = true;
    //         geometry.verticesNeedUpdate = true;
    //         geometry.normalsNeedUpdate = true;
    //         geometry.colorsNeedUpdate = true;
    //
    //     };
    //
    // }
    
    //变换顶点位置
    
    function vectorUpdate(value,object,flag){
        if(that.indexVector.length == 0) return;
        var target = that.indexVector;
        var i = target.length-1;
        var delta = value;
        var clipingFace = that.indexFace;
        var vertices = object.vertices.slice(0);
        for(;i>-1;i--){
            var vector = vertices[target[i]];
            switch (flag){
        
                //X变化
                case "L":
                    vector.z += delta;
                    clipingFace[""+flag+""].constant = 0.1-vector.z;
                    break;
                    
                case "R":
                    vector.z += delta;
                    clipingFace[""+flag+""].constant = 0.1+vector.z;
                    break;
        
                //Y变化
                case "T":
                    vector.y += -delta;
                    clipingFace[""+flag+""].constant = 0.1+vector.y;
                    break;
                    
                case "D":
                    vector.y += -delta;
                    clipingFace[""+flag+""].constant = -0.1-vector.y;
                    break;
        
                case "B":
                    vector.x += -delta;
                    clipingFace[""+flag+""].constant = 0.1-vector.x;
                    break;
                    
                case "F":
                    vector.x += delta;
                    clipingFace[""+flag+""].constant = 0.1+vector.x;
                    break;
        
            }
        }
        object.vertices = vertices;
        object.verticesNeedUpdate = true;
    }
    
    //目标面识别
    function faceId(){
    
    
    }
    
    //改变顶点颜色
    function changeColor(faceobj,indexa,indexb,color){
        var i = 0;
        var objectA = faceobj[indexa];
        var objectB = faceobj[indexb];
        var n = ( objectA instanceof THREE.Face3 ) ? 3 : 4;
        for(;i<n;i++){
            objectA.color.copy(new THREE.Color(color));
            objectB.color.copy(new THREE.Color(color));
        }
        that.indexVector = [];
        that.indexVector.push(objectA.a,objectA.b,objectA.c,objectB.b);
        
        // faceobj[indexa].forEach(function (value) {  });vertexColors[0] = color;
        // faceobj[indexa].vertexColors[2] = color;
        // faceobj[indexa].color.add(color);
        // faceobj[indexb].color.add(color);
        // faceobj[indexb].vertexColors[1] = color;
        // faceobj[indexb].vertexColors[2] = color;
        // faceobj[indexb].vertexColors[0] = color;
        
    }
    
    //提取指定顶点和面的数据
    function extractVertices(event,geometry) {
        var vessel = [];
        var objectA = faceobj[indexa];
        var objectB = faceobj[indexb];
        vessel.push(objectA.a,objectA.b,objectA.c,objectB.b);
        
        
    
    }
    
    
    return Cliping;
});